本笔记共四篇
Koa 源码阅读笔记(1) – co > Koa 源码阅读笔记(2) – compose > Koa 源码阅读笔记(3) – 服务器の启动与请求处理 > Koa 源码阅读笔记(4) – ctx 对象
起因
自从写了个 Koa 的脚手架koa2-easy,愈发觉得 Koa 的精妙。
于是抱着知其然也要知其所以然的想法,开始阅读 Koa 的源代码。
问题
读 Koa 源代码时,自然是带着诸多问题的。无论是上一篇所写的generator
函数如何自动执行,还是对于 Koa 中间件如何加载,next 参数如何来的。都充满了好奇。
今天写文章,并不是介绍整个koa-compose
如何如何(涉及太宽,准备放在下面几篇统一介绍)。而是从自身需求出发,找到问题的答案。
而问题就是Koa 中间件的加载,和 next 参数的来源。
源码解读
初始化与中间件加载
首先的是 Koa 加载初始化时的函数(删除部分):
1 | // Koa类 |
在这儿不难看出,Koa 对象内部有个中间件的数组,其中所有中间件都会存在其中。
而在服务器启动时,则会调用并处理该数组。
源代码如下:
1 | var co = require('co'); |
在 fn 被处理完后,每当有新请求,便会调用 fn,去处理请求。
而在这里,co.wrap 的作用是返回一个Promise
函数,用于后续自动执行generator
函数。
koa-compose
于是不难看出,中间件这儿的重点,是 compose 函数。
而 compose 函数的源代码虽然很简洁,但是也很烧脑。(对我而言)
1 | /** |
在这里,得提一提Koa
中间件的调用方式。
1 | app.use(function* (next) { |
在中间件中的 next,则是在koa-compose
中传入的。
而这儿, yield next
和 yield *next
也是有区别的。yield next
, next 会作为 next()的 value 返回。
而yield *next
则是在generator
函数内执行这个generator
函数。
结语
这两天一直在读 Koa 的源代码,细细看来不是很难,但是被作者的奇思妙想给打动了。
接下来会继续写一些阅读笔记,因为看 Koa 的源代码确实是获益匪浅。
前端路漫漫,且行且歌